<?php if (!defined('BASEPATH'))exit('No direct script access allowed');

include_once 'ExceptionDAO.php';
include_once 'TOItem.php';
include_once 'util/MapError.php';

/**
 * DAO para operações de banco para mídia (CD, DVD)
 * 
 * @author Douglas Rafael
 */
class DAOMidia extends CI_Model {
    var $erro_number;

    /**
     * Lista todas as mídias cadastradas.
     * 
     * @param int    $init      Posição inicial do cursor
     * @param int    $quant     Total de registros
     * @param string $orderby   Nome da coluna a ser ordenada
     * @param string $direction Direção: ASC ou DESC
     * @return array TOItem     Array de objetos
     * @throws ExceptionDAO
     * @throws Exception
     */
    public function select_all_media($init, $quant) {
        try {
            $this->db->select('item.codigo, item.titulo, item.subtitulo, item.ano, item.descricao, item.idioma, item.localizacao, item.imagem, item.data_cadastro, item.item_tipo_id, t.nome AS tipo_nome');
            $this->db->join('item_tipo t', 't.id = item_tipo_id');
            $this->db->where('item.item_tipo_id', TOItem::TIPO_MIDIA);
            $this->db->order_by('item.codigo', 'DESC');
            $result = $this->db->get('item', $quant, $init);

            //Caso ocorra erro no select
            if (!$result) {
                throw new Exception('Ocorreu um erro de banco de dados ao tentar listar as mídias.');
            } else {
                //Carregando models necessários
                $this->load->model('DAOCategoria');
                $midias = array();
                foreach ($result->result() as $value) {
                    $item = new TOItem();
                    $item->codigo = $value->codigo;
                    $item->titulo = $value->titulo;
                    $item->subtitulo = $value->subtitulo;
                    $item->descricao = $value->descricao;
                    $item->localizacao = $value->localizacao;
                    $item->imagem = $value->imagem;
                    $item->data_cadastro = $value->data_cadastro;
                    $item->idioma = $value->idioma;
                    
                    $item->midia = new TOMidia();
                    $item->midia->ano = $value->ano;

                    $item->tipo = new TOTipo();
                    $item->tipo->id = $value->item_tipo_id;
                    $item->tipo->nome = $value->tipo_nome;

                    //Categorias do Item
                    $item->categorias = $this->DAOCategoria->get_categories_item($item->codigo);

                    array_push($midias, $item);
                }
                return $midias;
            }
        } catch (Exception $e) {
            throw new ExceptionDAO($e->getMessage());
        }
    }
    
    
    /**
     * Retorna o Total geral de mídias cadastradas.
     * 
     * @return int Total de resgistros
     */
    public function amount_all_medias() {
        $this->db->where('item_tipo_id', TOItem::TIPO_MIDIA);
        return $this->db->count_all_results('item');
    }
    
    
    /**
     * Retorna a mídia de acordo com o código
     * 
     * @param TOItem $item
     * @return \TOItem
     * @throws ExceptionDAO
     * @throws Exception
     */
    public function get_media(TOItem $item) {
        try {
            $this->db->select('item.codigo, item.titulo, item.subtitulo, item.ano, item.descricao, item.idioma, item.localizacao, item.imagem, item.data_cadastro, item.item_tipo_id, t.nome AS tipo_nome, usuario_admin_id');
            $this->db->join('item_tipo t', 't.id = item_tipo_id');
            $this->db->where('item.item_tipo_id', TOItem::TIPO_MIDIA);
            $this->db->where('codigo', $item->codigo);
            $result = $this->db->get('item');

            //Caso ocorra erro no select
            if (!$result) {
                throw new Exception('Ocorreu um erro de banco de dados ao tentar selecionar mídia.');
            } else {
                $value = $result->row();

                $item = new TOItem();
                $item->codigo = $value->codigo;
                $item->titulo = $value->titulo;
                $item->subtitulo = $value->subtitulo;
                $item->descricao = $value->descricao;
                $item->localizacao = $value->localizacao;
                $item->imagem = $value->imagem;
                $item->data_cadastro = $value->data_cadastro;
                $item->idioma = $value->idioma;

                $item->midia = new TOMidia();
                $item->midia->ano = $value->ano;

                $item->tipo = new TOTipo();
                $item->tipo->id = $value->item_tipo_id;
                $item->tipo->nome = $value->tipo_nome;

                //Categorias do Item
                $this->load->model('DAOCategoria');
                $item->categorias = $this->DAOCategoria->get_categories_item($item->codigo);

                // Movimentação do Item
                $this->load->model('DAOMovimentacao');
                $item->movimentacao = $this->DAOMovimentacao->get_movimentacao_item($item->codigo);

                //Usuario Admin que cadastrou o item
                $this->load->model('DAOUsuario');
                $item->admin = $this->DAOUsuario->get_user($value->usuario_admin_id);

                return $item;
            }
        } catch (Exception $e) {
            throw new ExceptionDAO($e->getMessage());
        }
    }
    

    /**
     * Seleciona uma mídia de acordo com seu código
     * 
     * @param  TOItem $item     Obejto do item contendo o código do item a ser selecionado
     * @return TOItem           Item selecionado
     * @throws ExceptionDAO
     * @throws Exception
     */
    public function get_media_json(TOItem $item) {
        try {
            $this->db->select('item.codigo, item.titulo, item.subtitulo, item.ano, item.descricao, item.idioma, item.localizacao, item.imagem, item.data_cadastro, item.item_tipo_id, t.nome AS tipo_nome, usuario_admin_id');
            $this->db->join('item_tipo t', 't.id = item_tipo_id');
            $this->db->where('item.item_tipo_id', TOItem::TIPO_MIDIA);
            $this->db->where("codigo", $item->codigo);
            $result = $this->db->get('item');

            //Caso ocorra erro no select
            if (!$result) {
                throw new Exception('Ocorreu um erro de banco de dados ao tentar selecionar a mídia.');
            } else {
                $value = $result->row();

                $item = new TOItem();
                $item->codigo = $value->codigo;
                $item->titulo = $value->titulo;
                $item->subtitulo = $value->subtitulo;
                $item->descricao = $value->descricao;
                $item->localizacao = $value->localizacao;
                $item->imagem = $value->imagem;
                $item->data_cadastro = $value->data_cadastro;
                $item->idioma = $value->idioma;

                $item->midia = new TOMidia();
                $item->midia->ano = $value->ano;

                $item->tipo = new TOTipo();
                $item->tipo->id = $value->item_tipo_id;
                $item->tipo->nome = $value->tipo_nome;

                // Categorias do item
                $this->load->model('DAOCategoria');
                $item->categorias = $this->DAOCategoria->get_categories_item($value->codigo);

                // Movimentação do Item
                $this->load->model('DAOMovimentacao');
                $item->movimentacao = $this->DAOMovimentacao->get_movimentacao_item($item->codigo);

                // Emprestimos do item
                $this->load->model('DAOEmprestimo');
                $item->emprestimos = $this->DAOEmprestimo->get_loans_item($item->codigo, 0, 5);

                // Usuario Admin que cadastrou o item
                $this->load->model('DAOUsuario');
                $item->admin = $this->DAOUsuario->get_user($value->usuario_admin_id);

                return $item;
            }
        } catch (Exception $e) {
            throw new ExceptionDAO($e->getMessage());
        }
    }

    /**
     * Insere mídia
     * 
     * @param  TOItem $item
     * @throws ExceptionDAO
     * @throws Exception
     */
    public function insert_media(TOItem $item) {
        try {
            $this->db->trans_start();

            $this->db->set('titulo', $item->titulo);
            $this->db->set('subtitulo', $item->subtitulo);
            $this->db->set('ano', $item->midia->ano);
            $this->db->set('descricao', $item->descricao);
            $this->db->set('idioma', $item->idioma);
            $this->db->set('localizacao', $item->localizacao);
            $this->db->set('imagem', $item->imagem);
            $this->db->set('data_cadastro', $item->data_cadastro);
            $this->db->set('usuario_admin_id', $item->admin->id);
            $this->db->set('item_tipo_id', $item->tipo->id);
            
            $result = $this->db->insert('item');
            
            //cerifica se ocorreu tudo bem no insert
            if (!$result) {
                //Pegando numero do erro
                $this->db->_error_number() ? $this->erro_number = $this->db->_error_number() : '';
                throw new Exception();
            } else {
                $item->codigo = $this->db->insert_id(); // Pegendo o id do item inserido
                //INSERIR categorias
                $this->load->model('DAOCategoria');
                $this->DAOCategoria->insert_category_item($item);

                //INSERIR movimentacao
                $this->load->model('DAOMovimentacao');
                $this->DAOMovimentacao->insert_movimentacao($item);

                $this->db->trans_complete();

                if ($this->db->trans_status() === FALSE) {
                    throw new Exception('Ocorreu um erro de banco de dados ao tentar inserir o item.');
                }
            }
        } catch (Exception $e) {
            //Se foi feito o upload da imagem. A mesma é deletada
            if(!empty($item->imagem)){
                $this->Upload_image->delete_image($this->config->item('path_img_item') . 'media/', $item->imagem);
            }
            //Traduz o tipo de erro de acordo com $num
            $erro = new MapError();
            if(isset($this->erro_number)){
                 throw new ExceptionDAO($erro->getError($this->erro_number, NULL, $item->titulo));
            }else{
                 throw new ExceptionDAO($e->getMessage());
            }
        }
    }

    /**
     * Atualiza dados da mídia
     * 
     * @param  TOItem $item
     * @throws ExceptionDAO
     * @throws Exception
     */
    public function update_media(TOItem $item) {
        try {
            $this->db->trans_start();

            $this->db->set('titulo', $item->titulo);
            $this->db->set('subtitulo', $item->subtitulo);
            $this->db->set('ano', $item->midia->ano);
            $this->db->set('descricao', $item->descricao);
            $this->db->set('idioma', $item->idioma);
            $this->db->set('localizacao', $item->localizacao);
            $item->imagem != NULL ? $this->db->set('imagem', $item->imagem) : ''; // Verifica se a imagem foi atualizada
            $this->db->where('codigo', $item->codigo);
            
            $result = $this->db->update('item');
            
            //cerifica se ocorreu tudo bem no update
            if (!$result) {
                //Pegando numero do erro
                $this->db->_error_number() ? $this->erro_number = $this->db->_error_number() : '';
                throw new Exception();
            } else {
                //INSERIR categorias
                $this->load->model('DAOCategoria');
                $this->DAOCategoria->update_category_item($item);

                //INSERIR movimentacao
                $this->load->model('DAOMovimentacao');
                $this->DAOMovimentacao->update_movimentacao($item);

                $this->db->trans_complete();

                if ($this->db->trans_status() === FALSE) {
                    throw new Exception('Ocorreu um erro de banco de dados ao tentar atualizar o item.');
                }
            }
        } catch (Exception $e) {
            //Se foi feito o upload da imagem. A mesma é deletada
            if(!empty($item->imagem)){
                $this->Upload_image->delete_image($this->config->item('path_img_item') . 'media/', $item->imagem);
            }
            //Traduz o tipo de erro de acordo com $num
            $erro = new MapError();
            if(isset($this->erro_number)){
                 throw new ExceptionDAO($erro->getError($this->erro_number, NULL, $item->titulo));
            }else{
                 throw new ExceptionDAO($e->getMessage());
            }
        }
    }

    /**
     * Excluir mídia de acordo com o código.
     * 
     * @param  TOItem $item
     * @throws ExceptionDAO 
     */
    public function delete_media(TOItem $item) {
        try {
            $this->db->where('codigo', $item->codigo);
            $result = $this->db->delete('item');
            if (!$result) {
                throw new Exception();
            } else {
                if (!empty($item->imagem)) {
                    $this->load->model('UploadImage');
                    $this->UploadImage->delete_image($this->config->item('path_img_item') . 'media/', $item->imagem);
                }
            }
        } catch (Exception $e) {
            $erro = new MapError();
            throw new ExceptionDAO($erro->getError($this->db->_error_number(), $this->db->_error_message(), $item->titulo));
        }
    }

    /**
     * Efetua Busca por mídia.
     * 
     * @param int $init         Ponto Inicial do cursor no select
     * @param int $quant        Quantidade limite que deverá retornar o select
     * @param string $term      Termo a ser buscado
     * @return array TOItem     Array contendo os itens
     * @throws ExceptionDAO
     * @throws Exception
     */
    public function search_media($init, $quant, $term = NULL) {
        try {
            
            $this->db->select('item.codigo, item.titulo, item.subtitulo, item.ano, item.descricao, item.idioma, item.localizacao, item.imagem, item.data_cadastro, item.item_tipo_id, t.nome AS tipo_nome');
            $this->db->join('item_tipo t', 't.id = item_tipo_id');
            $this->db->join('categoria_has_item ci', 'ci.item_codigo = item.codigo', 'LEFT');
            $this->db->join('categoria c', 'ci.categoria_id = c.id' , 'LEFT');
            $this->db->where('(item.item_tipo_id = ' . TOItem::TIPO_MIDIA . ')');
            $this->db->where("(item.codigo LIKE '%" . $term . "%' OR item.titulo LIKE '%" . $term . "%' OR c.nome LIKE '%" . $term . "%')");
            $this->db->group_by('item.codigo', 'ASC');
            $this->db->order_by('item.codigo', 'ASC');
            $result = $this->db->get('item', $quant, $init);
            
            //Caso ocorra erro no select
            if (!$result) {
                throw new Exception('Ocorreu um erro de banco de dados ao tentar efetuar busca pela mídia.');
            } else {
                //Carregando models necessários
                $this->load->model('DAOCategoria');
                   $midias = array();
                foreach ($result->result() as $value) {
                    $item = new TOItem();
                    $item->codigo = $value->codigo;
                    $item->titulo = $value->titulo;
                    $item->subtitulo = $value->subtitulo;
                    $item->descricao = $value->descricao;
                    $item->localizacao = $value->localizacao;
                    $item->imagem = $value->imagem;
                    $item->data_cadastro = $value->data_cadastro;
                    $item->idioma = $value->idioma;
                    
                    $item->midia = new TOMidia();
                    $item->midia->ano = $value->ano;

                    $item->tipo = new TOTipo();
                    $item->tipo->id = $value->item_tipo_id;
                    $item->tipo->nome = $value->tipo_nome;

                    //Categorias do Item
                    $item->categorias = $this->DAOCategoria->get_categories_item($item->codigo);

                    array_push($midias, $item);
                }
                return $midias;
            }
        } catch (Exception $e) {
            throw new ExceptionDAO($e->getMessage());
        }
    }

    /**
     * Retorna a quantidade de registros da busca
     * 
     * @param string $term Termo a ser buscado
     * @return int
     */
    public function amount_search_media($term) {
        $this->db->join('item_tipo t', 't.id = item_tipo_id');
        $this->db->join('categoria_has_item ci', 'ci.item_codigo = item.codigo', 'LEFT');
        $this->db->join('categoria c', 'ci.categoria_id = c.id', 'LEFT');
        $this->db->where('(item.item_tipo_id = ' . TOItem::TIPO_MIDIA . ')');
        $this->db->where("(item.codigo LIKE '%" . $term . "%' OR item.titulo LIKE '%" . $term . "%' OR c.nome LIKE '%" . $term . "%')");
        $this->db->group_by('item.codigo', 'ASC');
        $result = $this->db->get('item');

        return count($result->result());
    }

}